﻿using System.Linq;
using ilgolosone.DomainModel.Entities;
using ilgolosone.DomainModel.Queries;
using ilgolosone.DomainModel.Repositories;
using ilgolosone.Persistence.NH.Data.Impl;
using NUnit.Framework;

namespace ilgolosone.Persistence.NH.UnitTests
{
    [TestFixture]
    public class RestaurantFixture : PersistenceFixtureBase
    {
        [Test]
        public void esistono_dei_dati_sui_ristoranti()
        {
            ConsumeUOW(uow =>
            {
                var repository = new NHibernateRepository<Restaurant>(uow);
                repository.Any().Should().Be.True();
            });
        }

        [Test]
        public void ricerca_di_un_ristorante_esistente()
        {
            const string RESTAURANT_TO_FIND = "Ristorante0";

            ConsumeUOW(uow =>
            {
                var repository = new NHibernateRepository<Restaurant>(uow);
                FindRestaurantByName query = new FindRestaurantByName(RESTAURANT_TO_FIND);
                IQueryable<Restaurant> result = repository.Filter(query);
                result.Should().Not.Be.Null();
                result.Single().RestaurantName.Should().Equals(RESTAURANT_TO_FIND);
            });
        }

        [Test]
        public void ricerca_di_un_insieme_di_ristoranti()
        {
            const int TEST_RESTAURANT_COUNT = 3;

            ConsumeUOW(uow =>
            {
                var repository = new NHibernateRepository<Restaurant>(uow);
                FindRestaurantByPartOfName query = new FindRestaurantByPartOfName("Rist");
                var result = repository.Filter(query).ToList();
                result.Should().Not.Be.Null();
                result.Count().Should().Be.Equals(TEST_RESTAURANT_COUNT);
            });
        }

        [Test]
        public void ricerca_di_un_ristorante_inesistente()
        {
            const string UNKNOWN_RESTAURANT_TO_FIND = "zzz";

            ConsumeUOW(uow =>
            {
                var repository = new NHibernateRepository<Restaurant>(uow);
                FindRestaurantByName query = new FindRestaurantByName(UNKNOWN_RESTAURANT_TO_FIND);
                var result = repository.Filter(query).FirstOrDefault();
                result.Should().Be.Null();
            });
        }

        [Test]
        public void modifica_di_un_ristorante()
        {
            const string RESTAURANT_TO_EDIT = "Ristorante0";
            const string NEW_RESTAURANT_NAME = "Ristorante modificato";

            FindRestaurantByName query = new FindRestaurantByName(RESTAURANT_TO_EDIT);

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Restaurant>(uow);
                    var result = repository.Filter(query).Single();
                    result.RestaurantName = NEW_RESTAURANT_NAME;
                    uow.Commit();
                });

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Restaurant>(uow);
                    var result = repository.Filter(query).FirstOrDefault();
                    result.Should().Be.Null();
                });
        }

        [Test]
        public void cancellazione_di_un_ristorante()
        {
            const string RESTAURANT_TO_DELETE = "Ristorante0";

            FindRestaurantByName query = new FindRestaurantByName(RESTAURANT_TO_DELETE);
            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Restaurant>(uow);
                    var result = repository.Filter(query).Single();
                    repository.Delete(result);
                    uow.Commit();
                });

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Restaurant>(uow);
                    var result = repository.Filter(query).FirstOrDefault();
                    result.Should().Be.Null();
                });
        }
    }
}
